#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#ifndef _HORIZONTAL_DATA_H_
#define _HORIZONTAL_DATA_H_
/***********************************************************************
  *Copyright 2020-05-03, pyfree
  *
  *File Name       : horizontal_data.h
  *File Mark       : 
  *Summary         : 
  *业务数据的横向数据管理模块,即信息点某时刻的态势集
  *目前数据为二层结构树[设备->点]
  *Current Version : 1.00
  *Author          : pyfree
  *FinishDate      :
  *
  *Replace Version :
  *Author          :
  *FinishDate      :

 ************************************************************************/
#include <map>

#include "Mutex.h"
#include "datadef.h"
#include "conf_app.h"
#include "conf_dev.h"
#include "conf_war.h"

class HorizontalData
{
protected:
    /* data */
    std::map<unsigned long long,pyfree::Dev> devs;
	PYMutex devs_point_mutex;//for point info change to lock
    //
    static float FLIMIT;
public:
    /**
     * 根据指定设备编号和点编号获取信息点的实时采集数值
     * @param _devID {ullong} 设备编号
     * @param _pID {uint} 点编号
     * @param _val {float&} 返回数值
     * @retuan {bool}  是否成功,主要是标识是否存在该信息点
     */
    bool getValue(unsigned long long _devID, unsigned int _pID, float &_val);
    /**
     * 根据指定设备编号和点编号获取信息点的实时计算数值
     * @param _devID {ullong} 设备编号
     * @param _pID {uint} 点编号
     * @param _val {float&} 返回数值
     * @retuan {bool}  是否成功,主要是标识是否存在该信息点
     */
    bool getCValue(unsigned long long _devID, unsigned int _pID, float &_val);
    /**
     * 根据指定设备编号、点编号、预期数值进行条件判定
     * @param _devID {ullong} 设备编号
     * @param _pID {uint} 点编号
     * @param rVal {float} 预期数值
     * @param _valMap {bool&} 值比较是否满足
     * @param _valChange {bool&} 数值本身是否发生变更
     * @param planf {bool} 是否为任务计划索取判定
     * @param comf {CompareType} 值比较类型
     * @retuan {bool}  是否成功,主要是标识是否存在该信息点
     */
    bool getConditionJude(unsigned long long _devID, unsigned int _pID, float rVal
	, bool &_valMap, bool &_valChange, bool planf, pyfree::CompareType comf);
    /**
     * 获取所有设备编号集合
     * @param _list {vector&} 设备编号集
     * @retuan {bool} true,容器不为空
     */
    bool getDevIDs(std::vector<long> &_list);
    /**
     * 获取所有设备信息
     * @param devs_ {vector&} 设备编号集
     * @param filter {bool} 是否过滤刷选,主要指信息点是否为订购点
     * @retuan {bool} true,容器不为空
     */
    bool getDevs(std::vector<pyfree::Dev> &devs_, bool filter);
    /**
     * 获取设备的已配置的阿里云物联网平台的三元组信息和功能标识符信息
     * @param deviceTriples {vector&} 设备编号集
     * @retuan {bool} true,容器不为空
     */
    bool getDevTriples(std::map<unsigned long long, pyfree::AliyunDevices> &deviceTriples);
    /**
     * 记缓存信息点实时数据
     * @param _devID {ullong}       设备编号
     * @param _pID {unit}           点编号
     * @param pret {PValueRet&}     点实时分析结果
     * @param isVirtualId {unit}    是否unit为虚拟点
     * @retuan {bool} true,存储成功
     */
    bool setHValue(unsigned long long _devID, unsigned int _pID, PValueRet &pret,bool isVirtualId=false);
protected:
    HorizontalData(/* args */);
    virtual ~HorizontalData();
protected:
    /**
     * 获取设备、点的描述信息以及事件信息
     * @param _devID {ullong}       设备编号
     * @param _pID {unit}           点编号
     * @param devDesc {string&}  设备描述
     * @param pDesc {string&}          点描述
     * @param eway_ {EventWay&}      事件方法
     * @retuan {bool} true,存储成功
     */
    void getAdditionalInfo(unsigned long long _devID, unsigned int _pID
		, std::string &devDesc, std::string &pDesc, pyfree::EventWay &eway_);
    /**
     * 上报虚拟点信息
     * @retuan {void}
     */
    void TimeUpVirtual();
    /**
     * 数据不刷新巡检
     * @retuan {void}
     */
    void TimeCheck();
    /**
     * 上报信息转发第三方平台虚函数,在子类具体实现
     * @param _wdlc {DataToThird&}  转发信息
     * @param ali_flag {bool}       转发阿里云物联网平台标识
     * @retuan {void}
     */
    virtual void send_data_to_third(const DataToThird &_wdlc,bool ali_flag=false)=0;
    /**
     * 添加事件信息到缓存虚函数,在子类具体实现
     * @param event_ {EventForWaring}  事件信息
     * @retuan {void}
     */
    virtual void add_event(EventForWaring event_)=0;
private:
    //私有内联函数,inline放置cpp
    /**
     * 数值比较
     * @param _fv {float}  前值
     * @param _tv {float}  后值
     * @param _ct {CompareType}  比较类型
     * @retuan {bool} 比对结果s
     */
    bool compareVal(float _fv, float _tv, pyfree::CompareType _ct);
    /**
     * 遥测跳变判定,(abs(新值-旧值)/abs(基准值))>百分比%
     * @param _oldval {float}  旧值
     * @param _newval {float}  新值
     * @param combase {float}  基准值
     * @param rate {float}  百分比数值
     * @retuan {bool} 判定结果
     */
    bool comBreak(float _oldval, float _newval, float combase, float rate);
    /**
     * 获取当天从凌晨开始到目前的时间,单位为分,并标识当前为月内哪天
     * @param day_ {int&}  月内的某天
     * @retuan {int} 分
     */
    int getCurTVMin(int &day_);
    /**
     * 当前时间是否在范围内,当startMin>endMin,跨天
     * @param curMin {int}    一天内的当前时间
     * @param startMin {int}  一天内的开始范围时间,[0,1440]
     * @param endMin {int}    一天内的结束范围时间,[0,1440]
     * @retuan {bool} 判定结果,是否在范围内
     */
    bool isMapTVMin(int curMin, int startMin, int endMin);
};


#endif
